import {
  asyncRoutes,
  constantRoutes,
  wxRouters,
  doctorRouters,
  managementRouter,
  settingRouters,
  customRouter
} from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles && route.meta.roles.length > 0) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = {...route}
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  accessRouters: [],
  wxRouters: [],
  settingRouters: [],
  doctorRouters: [],
  managementRouters: [],
  customRoutes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = unique(constantRoutes.concat(routes))
    state.accessRouters = state.routes
  },
  SET_ACCESS_ROUTES: (state, routes) => {
    state.accessRouters = routes
  },
  SET_WX_ROUTES: (state, routes) => {
    state.wxRouters = unique(constantRoutes.concat(routes))
  },
  SET_SETTING_ROUTES: (state, routes) => {
    state.settingRouters = unique(constantRoutes.concat(routes))
  },
  SET_DOCTOR_ROUTES: (state, routes) => {
    state.doctorRouters = unique(constantRoutes.concat(routes))
  },
  SET_MANAGEMENT_ROUTES: (state, routes) => {
    state.managementRouters = unique(constantRoutes.concat(routes))
  },
  SET_CUSTOMER_ROUTES: (state, routes) => {
    state.customRoutes = unique(constantRoutes.concat(routes))
  }
}

const actions = {
  accessRouters({commit}, roles) {
    commit('SET_ACCESS_ROUTES', roles)
  },
  generateRoutes({commit}, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      /* if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      } */

      let customerRouters
      customerRouters = filterAsyncRoutes(customRouter, roles)
      commit('SET_CUSTOMER_ROUTES', customerRouters)

      let accessedsettingRouters
      accessedsettingRouters = filterAsyncRoutes(settingRouters, roles)
      commit('SET_SETTING_ROUTES', accessedsettingRouters)

      let accessedWxRouters
      accessedWxRouters = filterAsyncRoutes(wxRouters, roles)
      commit('SET_WX_ROUTES', accessedWxRouters)

      let accessedDoctorRouters
      accessedDoctorRouters = filterAsyncRoutes(doctorRouters, roles)
      commit('SET_DOCTOR_ROUTES', accessedDoctorRouters)

      let accessedManagementRouters
      accessedManagementRouters = filterAsyncRoutes(managementRouter, roles)
      commit('SET_MANAGEMENT_ROUTES', accessedManagementRouters)

      accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)

      accessedRoutes = unique(accessedRoutes
          .concat(accessedsettingRouters)
        /*.concat(accessedManagementRouters)
        .concat(accessedDoctorRouters)
        .concat(customerRouters)
        .concat(accessedWxRouters)*/
      );

      commit('SET_ROUTES', accessedRoutes)

      let globalRouters = unique(accessedRoutes
        .concat(accessedsettingRouters)
        .concat(accessedManagementRouters)
        .concat(accessedDoctorRouters)
        .concat(customerRouters)
        .concat(accessedWxRouters)
      );


      resolve(globalRouters)
    })
  }
}

function unique(arr) {
  let m = {}
  arr = arr.filter(function (a) {
    if (!m[a.path]) {
      m[a.path] = 1
      return true
    }
    return false
  })
  return arr
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
